package com.dmagic.cms.entity;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Transient;

import jodd.util.StringUtil;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.Where;

import com.dmagic.cms.common.Constants;
import com.dmagic.cms.common.entity.ModifyInfoEntity;
import com.dmagic.cms.common.util.NumberUtil;
import com.dmagic.cms.common.util.reflection.ConvertUtil;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Table(name = "dmagic_appuser")
@Where(clause = ModifyInfoEntity.ISOBSOLETE_DATE_IS_NULL)
@JsonAutoDetect
@JsonIgnoreProperties(value = { "createdBy", "createdOn", "modifiedBy", "modifiedOn", "isObsoleteDate" })
public class AppUser extends ModifyInfoEntity implements Serializable {

	/**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = -6927714621777329243L;

	private Long appUserId;

	private String userName;

	private String password;

	private List<Permission> permissions;

	public AppUser() {
		super();
	}

	@Id
	@GeneratedValue(strategy = GenerationType.TABLE, generator = Constants.ID_GENERATOR)
	@TableGenerator(name = Constants.ID_GENERATOR, // Generator Name which same
													// with
	// generator
	table = Constants.ID_GENERATOR, // Generator Table Name
	pkColumnName = Constants.PK_COLUMNNAME, // Generator Table column Id name
	valueColumnName = Constants.VALUE_COLUMN_NAME, // Generator Table column Id
													// value
	pkColumnValue = "AppUser", // entity Name
	allocationSize = (Constants.ID_GENERATOR_ALLLCATIONSIZE), initialValue = Constants.ID_GENERATOR_INITIALVALUE)
	public Long getAppUserId() {
		return appUserId;
	}

	public void setAppUserId(Long appUserId) {
		this.appUserId = appUserId;
	}

	public String getUserName() {
		return userName;
	}

	@JsonIgnore
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	// 多对多定义
	@ManyToMany
	// 中间表定义,表名采用默认命名规则
	@JoinTable(name = "dmagic_appuser_permission", joinColumns = { @JoinColumn(name = "appUserId") }, inverseJoinColumns = { @JoinColumn(name = "permissionId") })
	// Fecth策略定义
	@Fetch(FetchMode.SUBSELECT)
	@OrderBy("permissionId")
	@JsonIgnore
	@Where(clause = ModifyInfoEntity.ISOBSOLETE_DATE_IS_NULL)
	public List<Permission> getPermissions() {
		return permissions;
	}

	public void setPermissions(List<Permission> permissions) {
		this.permissions = permissions;
	}

	/**
	 * 用户拥有的角色名称字符串, 多个角色名称用','分隔.
	 */
	// 非持久化属性.
	@Transient
	public String getPermissionNames() {
		return ConvertUtil.convertElementPropertyToString(permissions, "permissionName", ", ");
	}

	@Transient
	public String getPermissionNamesHtml() {
		return ConvertUtil.convertElementPropertyToString(permissions, "permissionName", "<br>");
	}

	/**
	 * 用户拥有的角色id字符串, 多个角色id用','分隔.
	 */
	// 非持久化属性.
	@Transient
	@SuppressWarnings("unchecked")
	public List<Long> getPermissionIds() {
		return ConvertUtil.convertElementPropertyToList(permissions, "permissionId");
	}

	@Override
	public boolean equals(Object appUserObject) {
		if (appUserObject == null)
			return false;
		AppUser appUser = (AppUser) appUserObject;
		if (NumberUtil.equals(this.appUserId, appUser.getAppUserId())
				|| StringUtil.equals(this.userName, appUser.getUserName())) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		return this.userName.hashCode();
	}
}
